package xyz.whiteblue.core;

import xyz.whiteblue.controller.Base;
import xyz.whiteblue.controller.Controller;
import xyz.whiteblue.controller.Mapping;
import xyz.whiteblue.interceptor.Interceptor;
import xyz.whiteblue.kit.StrKit;

import java.io.File;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by WhiteBlue on 15/6/14.
 */
public class PathUtil {
    private static ClassLoader classLoader;
    private static String ROOT_PATH;

    private PathUtil() {
        classLoader = getClass().getClassLoader();
    }

    public static PathUtil util = new PathUtil();


    /**
     * 得到包名
     */
    private String getPackage() {
        String allPackage = this.getClass().getPackage().getName().replaceAll(".core", "");
        return allPackage;
    }


    /**
     * 扫描组件
     */
    public void scanController(String filePath, Map<String, Class> mapUrl) throws ClassNotFoundException {
        File root = new File(filePath);
        File[] files = root.listFiles();
        for (File file : files) {
            if (file.isDirectory()) {
                scanController(file.getAbsolutePath(), mapUrl);
            } else {
                if (file.getName().endsWith("Controller.class")) {
                    Class preClass = classLoader.loadClass(getPackage() + "." + root.getName() + "." + file.getName().replace(".class", ""));
                    if (preClass.getSuperclass().equals(Controller.class)) {
                        Base base = (Base) preClass.getAnnotation(Base.class);
                        if (base == null)
                            continue;

                        String name = base.name();

                        if (name.startsWith("/"))
                            name = name.substring(1);

                        if (name.trim().equals(""))
                            name = "index";

                        mapUrl.put(name, preClass);
                    }
                }

                if (file.getName().endsWith("Config.class")) {
                    Class preClass = classLoader.loadClass(getPackage() + "." + root.getName() + "." + file.getName().replace(".class", ""));
                    if (preClass.getSuperclass().equals(SimpleConfig.class)) {
                        if (Config.getConfigClass() != null)
                            throw new RuntimeException("duplicate config class !!!");
                        else
                            Config.setConfigClass(preClass);
                    }
                }
            }
        }
    }

    /**
     * 扫描方法注解
     */
    public void scanMethod(Map<String, Class> urlMap, Map<Class, Map<String, Action>> map) {
        for (Class obj : urlMap.values()) {
            Map<String, Action> methodMap = new HashMap<String, Action>();
            for (Method method : obj.getMethods()) {
                Mapping mapping = method.getAnnotation(Mapping.class);

                if (mapping == null)
                    continue;

                String mapUrl = StrKit.clearUrl(mapping.name());

                Class<? extends Interceptor>[] interceptors = mapping.before();

                Action action = new Action(method, mapping.method(), interceptors);

                methodMap.put(mapUrl, action);
            }
            map.put(obj, methodMap);
        }
    }


    private List<String> readFromDirectory(String path) {
        File file = new File(path);
        String[] names = file.list();

        if (null == names)
            return null;

        return Arrays.asList(names);
    }


    private static String detectWebRootPath() {
        try {
            String e = PathUtil.class.getResource("/").toURI().getPath();
            return (new File(e)).getParentFile().getParentFile().getCanonicalPath();
        } catch (Exception var1) {
            throw new RuntimeException(var1);
        }
    }


    public static String getRootPath() {
        if (ROOT_PATH == null)
            ROOT_PATH = detectWebRootPath();
        return ROOT_PATH;
    }
}
